package org.mch.func.db.pdmfile;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.mch.comm.exec.MsgException;

public class PDMTableObjectTool {

	private File pdmFile;

	public PDMTableObjectTool(File file) {
		this.pdmFile = file;
	}

	@SuppressWarnings("rawtypes")
	public List<PDMTableObject> buildVOList() throws Exception {
		this.checkPdmFile();

		List<PDMTableObject> voS = new ArrayList<PDMTableObject>();

		PDMTableColumn[] cols = (PDMTableColumn[]) null;

		SAXReader sr = new SAXReader();
		Document doc = sr.read(this.getPdmFile());

		Iterator itr = doc.selectNodes("//c:Tables//o:Table").iterator();

		while (itr.hasNext()) {
			PDMTableObject tableObject = new PDMTableObject();
			cols = new PDMTableColumn[0];
			List<PDMTableColumn> list = new ArrayList<PDMTableColumn>();
			PDMTableColumn col = null;
			Element e_table = (Element) itr.next();
			tableObject.setTableName(e_table.elementTextTrim("Name"));
			tableObject.setTableCode(e_table.elementTextTrim("Code"));

			if (e_table.element("Columns") == null) {
				continue;
			}

			String keys_key_column_column_ref = null;
			try {
				keys_key_column_column_ref = this.checkPrimaryKey(e_table);
			} catch (MsgException mexce) {
				mexce.printStackTrace();
			}

			Iterator itr1 = e_table.element("Columns").elements("Column").iterator();

			String primarykey = null;
			while (itr1.hasNext()) {
				col = new PDMTableColumn();
				Element e_col = (Element) itr1.next();
				String pkID = e_col.attributeValue("Id");
				if (pkID.equals("o16")) {
					System.out.println();
				}
				col.setDefaultValue(e_col.elementTextTrim("DefaultValue"));
				col.setName(e_col.elementTextTrim("Name"));
				try {
					col.setType(e_col.elementTextTrim("DataType").substring(0, e_col.elementTextTrim("DataType").indexOf("(")));
				} catch (Exception ex) {
					col.setType(e_col.elementTextTrim("DataType"));
				}
				col.setCode(e_col.elementTextTrim("Code"));
				col.setLength(e_col.elementTextTrim("Length") == null ? null : Integer.valueOf(Integer.parseInt(e_col
						.elementTextTrim("Length"))));

				col.setPrecision(e_col.elementTextTrim("Precision") == null ? null : Integer.valueOf(Integer.parseInt(e_col
						.elementTextTrim("Precision"))));

				if (pkID.equals(keys_key_column_column_ref)) {
					col.setPkFlag(true);
					primarykey = col.getCode();
				}

				list.add(col);
			}
			tableObject.setPkField(primarykey);
			tableObject.setCols((PDMTableColumn[]) list.toArray(cols));
			voS.add(tableObject);
		}

		return voS;
	}

	/**
	 * 检查主键字段，并返回主键字段Id；
	 * 
	 * @param e_table
	 * @return
	 * @throws Exception
	 */
	private String checkPrimaryKey(Element e_table) throws Exception {
		String tableName = e_table.elementTextTrim("Name");

		try {
			Element pk_el = e_table.element("PrimaryKey");
			if (pk_el == null) {
				throw new MsgException("表" + tableName + "没有设置主键！");
			}
			String primarykey_ref_id = pk_el.element("Key").attributeValue("Ref");

			String keys_key_id = e_table.element("Keys").element("Key").attributeValue("Id");

			if (!primarykey_ref_id.equals(keys_key_id)) {
				throw new MsgException("表" + tableName + "没有设置主键！");
			}

			if (e_table.element("Keys").element("Key").element("Key.Columns").element("Column") != null) {
				String keys_key_column_column_ref = e_table.element("Keys").element("Key").element("Key.Columns")
						.element("Column").attributeValue("Ref");
				return keys_key_column_column_ref;
			} else {
				throw new MsgException("表" + tableName + "没有设置主键！");
			}

		} catch (MsgException e) {
			throw e;
		}
	}

	/**
	 * 
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public Map<String, PDMTableObject> buildVOMap() throws Exception {
		this.checkPdmFile();

		Map<String, PDMTableObject> voMap = new HashMap<String, PDMTableObject>();

		PDMTableColumn[] cols = (PDMTableColumn[]) null;

		SAXReader sr = new SAXReader();
		Document doc = null;
		try {
			doc = sr.read(this.getPdmFile());
		} catch (DocumentException e) {
			e.printStackTrace();
		}

		Iterator itr = doc.selectNodes("//c:Tables//o:Table").iterator();

		while (itr.hasNext()) {
			PDMTableObject tableObject = new PDMTableObject();
			cols = new PDMTableColumn[0];
			List<PDMTableColumn> list = new ArrayList<PDMTableColumn>();
			PDMTableColumn col = null;
			Element e_table = (Element) itr.next();
			tableObject.setTableName(e_table.elementTextTrim("Name"));
			tableObject.setTableCode(e_table.elementTextTrim("Code"));

			if (e_table.element("Columns") == null) {
				continue;
			}
			Iterator itr1 = e_table.element("Columns").elements("Column").iterator();
			while (itr1.hasNext()) {
				col = new PDMTableColumn();
				Element e_col = (Element) itr1.next();
				String pkID = e_col.attributeValue("Id");
				col.setDefaultValue(e_col.elementTextTrim("DefaultValue"));
				col.setName(e_col.elementTextTrim("Name"));
				try {
					col.setType(e_col.elementTextTrim("DataType").substring(0, e_col.elementTextTrim("DataType").indexOf("(")));
				} catch (Exception ex) {
					col.setType(e_col.elementTextTrim("DataType"));
				}
				col.setCode(e_col.elementTextTrim("Code"));
				col.setLength(e_col.elementTextTrim("Length") == null ? null : Integer.valueOf(Integer.parseInt(e_col
						.elementTextTrim("Length"))));

				col.setPrecision(e_col.elementTextTrim("Precision") == null ? null : Integer.valueOf(Integer.parseInt(e_col
						.elementTextTrim("Precision"))));

				String keys_key_id = e_table.element("Keys") != null ? null
						: e_table.element("Keys").element("Key") != null ? e_table.element("Keys").element("Key")
								.attributeValue("Id") : null;

				String keys_key_column_column_ref = null;
				if ((e_table.element("Keys") != null) && (e_table.element("Keys").element("Key") != null)
						&& (e_table.element("Keys").element("Key").element("Key.Columns") != null)) {
					if (e_table.element("Keys").element("Key").element("Key.Columns").element("Column") != null) {
						keys_key_column_column_ref = e_table.element("Keys").element("Key").element("Key.Columns")
								.element("Column").attributeValue("Ref");
					}

				}

				String keys_primarykey_ref_id = null;
				if ((e_table.element("PrimaryKey") != null) && (e_table.element("PrimaryKey").element("Key") != null)) {
					keys_primarykey_ref_id = e_table.element("PrimaryKey").element("Key").attributeValue("Ref");
				}

				try {
					if ((keys_primarykey_ref_id.equals(keys_key_id)) && (keys_key_column_column_ref.equals(pkID))) {
						col.setPkFlag(true);
						tableObject.setPkField(col.getCode());
					}
				} catch (Exception ex) {
					System.err.println("%%% 警告:[" + tableObject.getTableName() + "]未设置主键字段... %%%");
				}
				list.add(col);
			}

			tableObject.setCols((PDMTableColumn[]) list.toArray(cols));

			voMap.put(tableObject.getTableCode(), tableObject);
		}

		return voMap;
	}

	protected void checkPdmFile() throws MsgException {
		if (this.getPdmFile() == null) {
			throw new MsgException("PDM文件为空！");
		}
		if (!this.getPdmFile().isFile()) {
			throw new MsgException("传入的PDM文件不是一个标准文件！" + getPdmFile().getPath());
		}
		if (this.getPdmFile().isDirectory()) {
			throw new MsgException("伟入的PDM文件是一个目录！" + getPdmFile().getPath());
		}
	}

	public File getPdmFile() {
		return pdmFile;
	}

}